home *** CD-ROM | disk | FTP | other *** search
/ Network Support Library / RoseWare - Network Support Library.iso / manage / gtree.arc / HUNT.C < prev    next >
C/C++ Source or Header  |  1988-03-17  |  13KB  |  375 lines

  1. /**********************************************************************/
  2. /*                                                        */
  3. /*    HUNT.C                                                */
  4. /*                                                        */
  5. /*    This will search an entire drive for a given file spec.  Certain    */
  6. /*    options are available.  See the notes below for detail on these    */
  7. /*    options and command line switches.                            */
  8. /*                                                        */
  9. /**********************************************************************/
  10. /*                                                        */
  11. /*    Written    October 21, 1985                                */
  12. /*                                                        */
  13. /*    Author    David Midkiff -- D. M. Software And Systems            */
  14. /*                                                        */
  15. /**********************************************************************/
  16. /*                                                        */
  17. /*    Modified    December 13, 1986                                */
  18. /*            David Midkiff -- D. M. Software And Systems            */
  19. /*            Added the ability to delete the specified files.        */
  20. /*                                                        */
  21. /**********************************************************************/
  22. /*                                                        */
  23. /*    Modified    January 29, 1987                                */
  24. /*            David Midkiff -- D. M. Software And Systems            */
  25. /*            Changed the delete function to ask for operator        */
  26. /*            verification beforing deleting files, and the -v        */
  27. /*            command line switch to "pre"-verify deletions.        */
  28. /*                                                        */
  29. /**********************************************************************/
  30. /*                                                        */
  31. /*    Modified    December 1, 1987                                */
  32. /*            David Midkiff -- D. M. Software And Systems            */
  33. /*            This code was ported from the Lattice C compiler to    */
  34. /*            Turbo C.                                        */
  35. /*                                                        */
  36. /**********************************************************************/
  37. /*                                                        */
  38. /*    Modified    December 23, 1987                                */
  39. /*            David Midkiff -- D. M. Software And Systems            */
  40. /*            This was becoming unmanagable, so I removed the code    */
  41. /*            for file options and just it print a disk tree and I    */
  42. /*            changed the name to GTREE.C                        */
  43. /*                                                        */
  44. /**********************************************************************/
  45. /*                                                        */
  46. /*    Copyright (c) 1988 -- D. M. Software And Systems                */
  47. /*                                                        */
  48. /*    All rights reserved.  Do not redistribute this program without    */
  49. /*    this notice, or the notice in the main() function.            */
  50. /*                                                        */
  51. /*    This program is designed to be instructive and useful, however    */
  52. /*    there are no warranties expressed or implied.  Feel free to        */
  53. /*    use this program in any manner you see fit, with the exceptions    */
  54. /*    of commerical environments and redistribution for any fee.        */
  55. /*    You are feel free to redistribute this program to any bulletin    */
  56. /*    boards or user's group, provide no fee is charge for any service    */
  57. /*    you may provide.                                        */
  58. /*                                                        */
  59. /*    If you find this program useful, you are asked to send a $20    */
  60. /*    contribution towards its upkeep.  No support will be given to    */
  61. /*    unsupported users, except in the cases where the user needs to    */
  62. /*    find out if this program is suitable for his or her purposes.    */
  63. /*                                                        */
  64. /*    Send $20.00 contribution to:                                */
  65. /*        D. M. Software And Systems                            */
  66. /*        6572 Suson Woods Drive                                */
  67. /*        St. Louis, MO  63128                                */
  68. /*                                                        */
  69. /*    Remember, you do not have to send a contribution, but your        */
  70. /*    conscience will haunt you forever.                            */
  71. /*                                                        */
  72. /**********************************************************************/
  73.  
  74.  
  75. #include "stdio.h"
  76. #include "conio.h"
  77. #include "ctype.h"
  78. #include "dir.h"
  79. #include "dos.h"
  80. #include "io.h"
  81. #include "\dmlist\mylib.h"
  82. #include "stdlib.h"
  83. #include "string.h"
  84.  
  85. extern unsigned _stklen = 32678U ;        /* Need a larger than normal stack */
  86.                                 /* since buildtree() is recursive. */
  87.  
  88. /*PAGE*/
  89. /*******************************************************/
  90. /*                                            */
  91. /*        --- GLOBAL VARIABLE DEFINITIONS ---        */
  92. /*                                            */
  93. /*******************************************************/
  94.  
  95. #define ESCAPE (char) 27
  96.  
  97. #define MAXFILES 20
  98.  
  99. long bytesdeleted = 0L ;            /* Total bytes deleted */
  100.  
  101. int drive = -1 ;                /* Drive to use as a default */
  102.  
  103. int filesdeleted = 0 ;            /* Number of files deleted */
  104.  
  105. int killflag = 0 ;                /* 1 == Delete matching files */
  106.  
  107. int matches = 0 ;                /* Number of files matching entered file specs */
  108.  
  109. char scratch[256] ;                /* A scratch string */
  110.  
  111. char spaces[81] ;                /* A string of spaces for formatting output */
  112.  
  113. int spec_count = 0 ;            /* A count of inputted file spec's */
  114.  
  115. char specin[MAXFILES][80] ;        /* The inputted file spec's */
  116.  
  117. long totalbytes = 0L ;            /* Total bytes in all matching files */
  118.  
  119. int verified = 0 ;                /* 1 == Deletion request verified on the command line */
  120.  
  121. /*PAGE*/
  122. /***********************************/
  123. /*                            */
  124. /*        FUNCTION PROTOTYPES        */
  125. /*                            */
  126. /***********************************/
  127.  
  128. void buildtree( char *thisdirectory ) ;
  129. void fatalerr( char *message , int useflag ) ;
  130. void showusage( void ) ;
  131.  
  132.  
  133.  
  134. /*PAGE*/
  135. /**********************************************************************/
  136. /*                                                        */
  137. /*    BUILDTREE() - Build a directory tree from the passed name.  It     */
  138. /*                does not really build a tree since it is recursive    */
  139. /*                function.  Care should be used when changing this    */
  140. /*                routine!!!!  It works as it stands now.            */
  141. /*                                                        */
  142. /**********************************************************************/
  143.  
  144. void buildtree( p )
  145.     char *p ;                        /* Directory being searched */
  146. {
  147.  
  148.     struct ffblk dir ;                /* For directories */
  149.     int deleteflag ;                /* For deletion request */
  150.     struct ffblk file ;                /* For data files */
  151.     int i ;                        /* Scratch integer */
  152.     char newname[81] ;                /* String for formatting a name */
  153.     
  154.     printf( "\n%s" , p ) ;
  155.     for( i=0; i<spec_count; i++ )
  156.     {
  157.         (void) sprintf( newname , "%s%s" , p , &specin[i][0] ) ;
  158.         if( !findfirst( newname , &file , 0 ) )
  159.         {
  160.             do
  161.             {
  162.                 printf( "\n%*s%-12.12s" , strlen(p) , "" , file.ff_name ) ;
  163.                 totalbytes = totalbytes + file.ff_fsize ;
  164.                 matches++ ;
  165.                 if( killflag )
  166.                 {
  167.                     if( !verified )
  168.                     {
  169.                         printf( " -- Delete (Y or N)? " ) ;
  170.                         do
  171.                         {
  172.                             deleteflag = toupper( getche() ) ;
  173.                             if( deleteflag == ESCAPE )
  174.                                 exit( 2 ) ;
  175.                         } while( deleteflag != 'Y' && deleteflag != 'N' ) ;
  176.                     }
  177.                     if( deleteflag == 'Y' || verified )
  178.                     {
  179.                         (void) sprintf( scratch , "%s%s" , p , file.ff_name ) ;
  180.                         if( unlink( scratch ) )
  181.                             printf( " -- cannot be delete" ) ;
  182.                         else
  183.                         {
  184.                             printf( " -- Deleted" ) ;
  185.                             bytesdeleted = bytesdeleted + file.ff_fsize ;
  186.                             filesdeleted++ ;
  187.                         }    /* if( unlink( scratch ) )....else....*/
  188.                     }    /* if( deleteflag == 'Y' || verified ) */
  189.                     else
  190.                         printf( " -- ignored" ) ;
  191.                 }    /* if( killflag ) */
  192.             } while( !findnext( &file ) ) ;
  193.         }    /* if( !findfirst( newname , &file , 0 ) ) */
  194.     }    /* for( i=0; i<spec_count; i++ ) */
  195.  
  196.     (void) sprintf( newname , "%s*.*" , p ) ;
  197.     if( !findfirst( newname , &dir , FA_DIREC ) )
  198.     {
  199.         do
  200.         {
  201.             if( dir.ff_attrib == FA_DIREC && dir.ff_name[0] != '.' )
  202.             {
  203.                 (void) sprintf( newname , "%s%s\\" , p , dir.ff_name ) ;
  204.                 buildtree( newname ) ;
  205.             }    /* if( dir.ff_attrib == FA_DIREC && dir.ff_name[0] != '.' ) */
  206.         } while( !findnext( &dir ) ) ;
  207.     }    /* if( !findfirst( newname , dir , FA_DIREC ) ) */
  208.  
  209.     return ;
  210.     
  211. }    /* end of buildtree() */
  212.  
  213. /*PAGE*/
  214. /**********************************************************************/
  215. /*                                                        */
  216. /*    FATALERR() - Print a fatal error message and exit after setting    */
  217. /*               the DOS ERRORLEVEL variable to 1.                */
  218. /*                                                        */
  219. /**********************************************************************/
  220.  
  221. void fatalerr( msg , useflag )
  222.     char *msg ;                /* Part of error message to print */
  223.     int useflag ;                /* 1 == Show usage before exiting */
  224. {
  225.  
  226.     printf( "\n %s -- HUNT canceled\n" , msg ) ;
  227.     if( useflag )
  228.         showusage() ;
  229.         
  230.     exit( 1 ) ;
  231.     
  232.     return ;        /* sic */
  233.     
  234. }    /* end of fatal error */
  235.  
  236. /*page*/
  237. /**********************************************************************/
  238. /*                                                        */
  239. /*    MAIN() -    This is the main processing function.  The only things    */
  240. /*                that are processed here are command line parameters.    */
  241. /*            The process is:                                */
  242. /*                1.) Process command line arguements.            */
  243. /*                2.) Check for a drive assignment.  If not present    */
  244. /*                    use the default drive.                    */
  245. /*                3.) Format the root file name by inserting the    */
  246. /*                    drive letter to give C:\, for example.        */
  247. /*                4.) Call the buildtree() function with the root    */
  248. /*                    direcorty to get started.                    */
  249. /*                5.) Print any of the requested statistics.        */
  250. /*                                                        */
  251. /**********************************************************************/
  252.  
  253. void main( argc , argv )
  254.     int argc ;
  255.     char *argv[] ;
  256. {
  257.  
  258.     int i ;                        /* A scratch integer */
  259.     char root[8] ;                    /* For the formatted root file name */
  260.     (void) puts( "HUNT -- Version 1.0 - March 1988\nCopyright (c) 1988.  D. M. Software and Systems.  All rights reserved." ) ;
  261.  
  262.     if( argc == 1 )
  263.         fatalerr( "I have no work to do!!" , 1 ) ;
  264.     
  265.     (void) sprintf( spaces , "%80.80s" , "" ) ;    /* Make an 80 character string of spaces */
  266.     
  267.     for( i=1; i<argc; i++ )                    /* Parse the command line arguments */
  268.     {
  269.         if( *argv[i] != '-' && *argv[i] != '/' )
  270.         {
  271.             if( *(argv[i]+1) != ':' )
  272.                 strupper( &specin[spec_count++][0] , argv[i] ) ;
  273.             else
  274.             {
  275.                 if( drive != -1 )
  276.                     fatalerr( "More than one drive specification passed" , 1 ) ;
  277.                 drive = tolower( *argv[i] ) ;
  278.                 if( strlen( argv[i] ) != 2 || drive < 'a' || drive > 'z' )
  279.                     fatalerr( "Invalid drive specification" , 1 ) ;
  280.             }    /* if( *(argv[i]+1) != ':' ) */
  281.         }    /* if( *argv[i] != '-' && *argv[i] != '/' ) */
  282.         else
  283.         {
  284.             switch( tolower( *(argv[i]+1) ) )
  285.             {
  286.                 case 'h' :        /* Show usage only */
  287.                     showusage() ;
  288.                     exit( 1 ) ;
  289.                     break ;
  290.                 case 'k' :        /* Set the kill flag */
  291.                     killflag = 1 ;
  292.                     break ;
  293.                 case 'v' :        /* Pre-verify deletion request */
  294.                     verified = 1 ;
  295.                     break ;
  296.                 default :            /* Invalid switch */
  297.                     (void) sprintf( scratch , "%s is an invalid parameter" , argv[i] ) ;
  298.                     fatalerr( scratch , 0 ) ;    
  299.             }    /* end case/switch( tolower( *(argv[i]+1) ) ) */
  300.         }    /* if( *argv[i] != '-' && *argv[i] != '/' ) */
  301.     }    /* for( i=1; iargc; i++ ) */
  302.     
  303.     if( drive == -1 )                        /* Set drive to the current drive */
  304.         drive = getdisk() ;                    /* of not set by the operator.    */
  305.         
  306.     drive += 'A' ;                            /* Convert to alpha */
  307.             
  308.     (void) sprintf( root , "%c:\\" , drive ) ;    /* Format for buildtree()'s initial call */
  309.     buildtree( root ) ;
  310.     
  311.     printf( "\n%ld bytes found in %d files." , totalbytes , matches ) ;
  312.     if( killflag )
  313.         printf( "  %ld bytes and %d files were deleted." , bytesdeleted , filesdeleted ) ;
  314.     
  315.     exit( 0 ) ;
  316.     
  317. }    /* end of main() */
  318.  
  319.  
  320. /**********************************************************************/
  321. /*                                                        */
  322. /*    SHOWUSAGE() - Prints the usage message that appears at runtime.    */
  323. /*                This can be called by a -h on the command line or    */
  324. /*                by certan errors via fatalerr() above.            */
  325. /*                                                        */
  326. /**********************************************************************/
  327.  
  328. void showusage()
  329. {
  330.  
  331.     (void) puts( "\nUsage is hunt [drive:] [-flags] [filespec] where:" ) ;
  332.     (void) puts( "\tdrive: - to override default drive specification." ) ;
  333.     (void) puts( "\t-H for help.  Displays this message." ) ;
  334.     (void) puts( "\t-K for kill.  Delete matching files." ) ;
  335.     (void) puts( "\t-V for verify.  \"Preverify\" deletion request." ) ;
  336.     
  337.     return ;
  338.     
  339. }    /* end of showusage() */
  340.  
  341. /*******************************************************/
  342. /*                                                     */
  343. /*   STRUPPER()                                        */
  344. /*                                                     */
  345. /*   Copies a string and converts it to upper case.    */
  346. /*        On Calling:                            */
  347. /*            dest == the destionation string.        */
  348. /*            src == The source string.            */
  349. /*        Returns:                                */
  350. /*            Nothing                            */
  351. /*                                                     */
  352. /*******************************************************/
  353.  
  354. void strupper( dest , src )
  355.     char *dest ;            /* Destination string */
  356.     char *src ;            /* Source string      */
  357. {
  358.  
  359.     while( *src )
  360.     {
  361.         *dest++ = toupper( *src ) ;    /* BE CAREFUL...toupper is a macro */
  362.         src++ ;
  363.     }    /* while( *dest ) */
  364.     *dest = '\0' ;
  365.     
  366.     return ;
  367.     
  368. }    /* end of strupper() */
  369.  
  370.  
  371. /*************************/
  372. /*                    */
  373. /*    END OF HUNT.C        */
  374. /*                    */
  375. /*************************/